package com.sas.domain;

import javax.persistence.Entity;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.Type;
import org.joda.time.DateTime;
import org.springframework.util.Assert;

@Entity
public class Flow extends PersistentEntity {
	public static enum FlowType {PURCHASE, SALE, RETURNFROM, RETURNTO, LOST};
	
	@NaturalId
	@Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
	private DateTime date;
	@NaturalId
	private FlowType flowType;
	
	@NaturalId
	@ManyToOne
	private Article article;
	
	private Integer amount;
	private Double price;
	private Double finalPrice;
	private Double discount;
	private Double surcharge;
	
	@ManyToOne
	private Client client;
	
	@ManyToOne
	private Vendor vendor;
	
	Flow () {
	}

	public Flow(DateTime dateTime, FlowType type, Article art,
			Double priceSell, int amount, double finalPrice, double discount, double surcharge,
			Client client, Vendor vendor) {
		setDate(dateTime);
		setFlowType(type);
		setArticle(art);
		setPrice(priceSell);
		setAmount(amount);
		setFinalPrice(finalPrice);
		setDiscount(discount);
		setSurcharge(surcharge);
		setClient(client);
		setVendor(vendor);
		
	}

	public DateTime getDate() {
		return date;
	}

	public void setDate(DateTime date) {
		Assert.notNull(date);
		this.date = date;
	}

	public FlowType getFlowType() {
		return flowType;
	}

	public void setFlowType(FlowType flowType) {
		Assert.notNull(flowType);
		this.flowType = flowType;
	}

	public Article getArticle() {
		return article;
	}

	public void setArticle(Article article) {
		Assert.notNull(article);
		this.article = article;
	}

	public void setPrice(Double price) {
		Assert.notNull(price);
		Assert.state(price >= 0);
		this.price = price;
	}

	public Double getPrice() {
		return price;
	}

	public void setClient(Client client) {
		Assert.notNull(client);
		this.client = client;
	}

	public Client getClient() {
		return client;
	}

	public void setDiscount(Double discount) {
		this.discount = discount;
	}

	public Double getDiscount() {
		return discount;
	}

	public void setSurcharge(Double surcharge) {
		this.surcharge = surcharge;
	}

	public Double getSurcharge() {
		return surcharge;
	}

	public void setFinalPrice(Double finalPrice) {
		this.finalPrice = finalPrice;
	}

	public Double getFinalPrice() {
		return finalPrice;
	}

	public void setVendor(Vendor vendor) {
		this.vendor = vendor;
	}

	public Vendor getVendor() {
		return vendor;
	}
	
	public Integer getAmount() {
		return amount;
	}

	public void setAmount(Integer amount) {
		this.amount = amount;
	}

	public Subject getSubject() {
		if (flowType == null) {
			return null;
		}
		
		if (flowType.equals(Flow.FlowType.LOST)
				|| flowType.equals(Flow.FlowType.PURCHASE)
				|| flowType.equals(Flow.FlowType.RETURNTO)) {
			return vendor;
		}
		
		if (flowType.equals(Flow.FlowType.SALE) 
				|| flowType.equals(Flow.FlowType.RETURNFROM)) {
			return client; 
		}
		
		throw new RuntimeException("Error geting subject from flow");
		
	}

}
